import openai
import os
import chardet
from typing import List, Dict

class SmartExamBot:
    def __init__(self, api_key: str, base_url: str):
        """
        初始化考试机器人
        :param api_key: OpenAI API密钥
        :param base_url: API基础URL
        """
        self.api_key = api_key
        self.base_url = base_url
        self.client = openai.OpenAI(api_key=api_key, base_url=base_url)
        self.max_follow_ups = 3  # 每道题最大追问次数
        self.question_count = 0  # 题目计数
        self.total_score = 0  # 总分
        self.max_possible_score = 0  # 可能获得的最高分

    @staticmethod
    def detect_encoding(file_path: str) -> str:
        """检测文件编码"""
        with open(file_path, 'rb') as file:
            return chardet.detect(file.read(10240))['encoding']

    def read_file_content(self, file_path: str) -> str:
        """读取文件内容"""
        try:
            encoding = self.detect_encoding(file_path)
            with open(file_path, 'r', encoding=encoding) as file:
                return file.read()
        except Exception as e:
            raise Exception(f"文件读取失败: {str(e)}")

    def get_ai_response(self, messages: List[Dict]) -> str:
        """获取AI响应"""
        try:
            response = self.client.chat.completions.create(
                model="gpt-4-turbo",
                messages=messages
            )
            return response.choices[0].message.content
        except Exception as e:
            raise Exception(f"API请求失败: {str(e)}")

    def start_exam(self, knowledge_content: str):
        """开始考试流程"""
        print("\n" + "=" * 50)
        print("智能考试机器人".center(40))
        print("=" * 50)
        print("\n我将根据提供的知识内容对你进行考察。")
        print(f"每道题会有最多{self.max_follow_ups}次追问。")
        print("输入'开始'即可开始考试")
        print("输入'退出'可随时结束考试。\n")

        # 初始化对话历史
        messages = [
            {"role": "system", "content": f"""
            你是一个专业严谨的智能考试机器人，基于以下知识内容出题和评分:
            {knowledge_content}

            评分标准:
            1. 答案准确性(0-4分)
            2. 回答完整性(0-3分)
            3. 逻辑清晰度(0-3分)

            每次评分后请按以下格式返回:
            分数(0-10)|具体反馈|是否追问(是/否)
            """},
            {"role": "assistant", "content": "我已准备好开始考试。请输入'开始'进行第一题。"}
        ]

        while True:
            user_input = input("\n你: ").strip()

            if user_input.lower() == '退出':
                self._show_final_score()
                break

            if user_input.lower() == '开始' or user_input.lower() == '继续':
                self._handle_new_question(messages)
            else:
                self._handle_user_answer(user_input, messages)

    def _handle_new_question(self, messages: List[Dict]):
        """处理新题目"""
        self.question_count += 1
        follow_up_count = 0

        # 获取新题目
        messages.append({"role": "user", "content": "请出一道有深度的主观题"})
        question = self.get_ai_response(messages)
        messages.append({"role": "assistant", "content": question})

        print(f"\n[第{self.question_count}题] 考试机器人: {question}")
        self.max_possible_score += 10  # 每道题满分10分

    def _handle_user_answer(self, user_answer: str, messages: List[Dict]):
        """处理用户回答"""
        messages.append({"role": "user", "content": user_answer})

        # 获取评估
        evaluation = self.get_ai_response(messages + [
            {"role": "assistant", "content": "请按照要求的格式进行评分和反馈"}
        ])
        print(f"AI 原始返回：{evaluation}")

        try:
            score, feedback, need_follow_up = evaluation.split("|")
            score = float(score.strip())
            feedback = feedback.strip()
            need_follow_up = need_follow_up.strip().lower() == '是'

            self.total_score += score
            current_question_num = len([m for m in messages if m['role'] == 'assistant' and '追问' not in m['content']])

            print(f"\n评分: {score}/10")
            print(f"反馈: {feedback}")
            print(f"累计得分: {self.total_score}/{self.max_possible_score}")

            if need_follow_up:
                follow_up_count = sum(1 for m in messages if '追问' in m.get('content', ''))
                if follow_up_count < self.max_follow_ups:
                    self._ask_follow_up(messages)
                else:
                    print("\n已达到最大追问次数，请输入'继续'进入下一题。")
            else:
                print("\n本题结束，请输入'继续'进入下一题。")

        except Exception as e:
            print(f"\n评分解析失败: {str(e)}")

    def _ask_follow_up(self, messages: List[Dict]):
        """提出追问问题"""
        follow_up_question = self.get_ai_response(messages + [
            {"role": "assistant", "content": "请提出一个有针对性的追问问题"}
        ])
        messages.append({"role": "assistant", "content": f"[追问] {follow_up_question}"})
        print(f"\n考试机器人 [追问]: {follow_up_question}")

    def _show_final_score(self):
        """显示最终得分"""
        print("\n" + "=" * 50)
        if self.question_count > 0:
            percentage = (self.total_score / self.max_possible_score) * 100
            print(f"\n考试结束！共完成 {self.question_count} 道题")
            print(f"最终得分: {self.total_score}/{self.max_possible_score} ({percentage:.1f}%)")

            if percentage >= 80:
                print("成绩优秀！你对知识点的掌握非常扎实。")
            elif percentage >= 60:
                print("成绩良好！对主要内容有较好理解，但还有提升空间。")
            else:
                print("需要加强学习！建议回顾相关知识点。")
        else:
            print("本次未完成任何题目。")
        print("=" * 50 + "\n")


if __name__ == "__main__":
    # 配置信息
    CONFIG = {
        "api_key": "sk-ThA0WI5NVgQ1xYUf8BriyRJfIqBWRvbV5rrzmAWBvdjxsnWP",
        "base_url": "https://yibuapi.com/v1",
        "file_path": r"D:\桌面\竞赛\挑战杯+人工智能\第3章 数据获取.txt"
    }

    try:
        # 创建考试机器人实例
        exam_bot = SmartExamBot(api_key=CONFIG["api_key"], base_url=CONFIG["base_url"])

        # 读取知识内容
        knowledge_content = exam_bot.read_file_content(CONFIG["file_path"])
        print(f"成功加载知识内容，长度: {len(knowledge_content)} 字符")

        # 开始考试
        exam_bot.start_exam(knowledge_content)

    except Exception as e:
        print(f"程序运行出错: {str(e)}")
    finally:
        input("按回车键退出...")